<template>
  <div class="pagination">
    <ul class="pagination-btns">
      <li @click="count" :class="{ disabled: myCurrentPage <= 1 }">
        <span class="iconfont icon-arrow-left-bold"></span>
      </li>
      <!-- 最前面的按钮 -->
      <li :class="{ active: myCurrentPage === 1 }" @click="myCurrentPage = 1">
        1
      </li>
      <!-- 省略号 -->
      <li v-if="startEnd.start > 2">
        <span class="iconfont icon-elipsis"></span>
      </li>
      <!-- 中间按钮 -->
      <li
        v-for="(number, index) in startEnd.end - startEnd.start + 1"
        :key="startEnd.start + index"
        :class="{ active: myCurrentPage === startEnd.start + index }"
        @click="myCurrentPage = startEnd.start + index"
      >
        {{ startEnd.start + index }}
      </li>
      <li v-if="startEnd.end < totalPages - 1">
        <span class="iconfont icon-elipsis"></span>
      </li>
      <!-- 最后面的按钮 -->
      <li
        v-if="totalPages > 1"
        :class="{ active: myCurrentPage === totalPages }"
        @click="myCurrentPage = totalPages"
      >
        {{ totalPages }}
      </li>
      <li @click="add" :class="{ disabled: myCurrentPage >= totalPages }">
        <span class="iconfont icon-arrow-right-bold"></span>
      </li>
    </ul>
    <select class="pagination-select" v-model="myPageSize">
      <option :value="5">每页 5 条</option>
      <option :value="10">每页 10 条</option>
      <option :value="15">每页 15 条</option>
      <option :value="20">每页 20 条</option>
    </select>
    <span class="pagination-total">总 {{ total }} 条</span>
  </div>
</template>

<script>

/*
  函数节流：让函数在单位时间内只调用一次，第一次调用
    mousemove
    scroll
  函数防抖：让函数在单位时间内只调用一次，最后一次调用
    搜索功能
      优化函数的性能（让函数在单位时间内调用次数更少）
*/
export default {
  name: "Pagination",
  props: {
    // 当前页码
    currentPage: {
      type: Number,
      default: 1,
    },
    // 每页条数
    pageSize: {
      type: Number,
      default: 5,
    },
    // 总数
    total: {
      type: Number,
      default: 0,
    },
  },
  data() {
    return {
      myCurrentPage: this.currentPage,
      myPageSize: this.pageSize,
      isEmit: false,
    };
  },
  computed: {
    // 总页数
    totalPages() {
      return Math.ceil(this.total / this.myPageSize);
    },
    // 中间按钮start和end（不包含头和尾）
    startEnd() {
      /*
        场景1：
          1 ... 3 4 [5] 6 7 ... 44

          [5] currentPage

          计算：
            start = currentPage - 2
            end = currentPage + 2
            end = start + 4

        场景2：
          1 [2] 3 4 5 6 ... 44

          [2] currentPage

          按照上面公式计算：
            start = 2 - 2 = 0
            end = 0 + 4 = 4

          解决：
            中间按钮是有最小值的 2
            if (start < 2) start = 2;

            start = 2 - 2 = 0 --> 2
            end = 2 + 4 = 6

        场景3：
          1 ... 39 40 41 42 [43] 44

          [43] currentPage

          按照上面公式计算：
            start = 43 - 2 = 41
            end = 41 + 4 = 45

          解决：
            中间按钮是有最大值的 totalPages - 1
            if (end > totalPages - 1) {
              end = totalPages - 1;
              start = end - 4;
            }

        场景4：
          1 2 3 [4] 5

          [4] currentPage

          按照上面公式计算：
            start = 4 - 2 = 2
            end = 2 + 4 = 6 --> 4
              start --> 4 - 4 = 0

          解决：
            if (totalPages <= 7) {
              return {
                start: 2,
                end: totalPages - 1
              }
            }

        场景5： 没有中间按钮
          [1]
          1 [2]

          end - start + 1 === 0
      */
      const { myCurrentPage, totalPages } = this;

      if (totalPages <= 1) {
        return {
          start: 2,
          end: 1,
        };
      }

      if (totalPages <= 7) {
        return {
          start: 2,
          end: totalPages - 1,
        };
      }

      let start = myCurrentPage - 2;
      if (start < 2) start = 2;

      let end = start + 4;
      if (end > totalPages - 1) {
        end = totalPages - 1;
        start = end - 4;
      }

      return {
        start,
        end,
      };
    },
  },
  methods: {
    count() {
      if (this.myCurrentPage <= 1) return;
      this.myCurrentPage--;
    },
    add() {
      if (this.myCurrentPage >= this.totalPages) return;
      this.myCurrentPage++;
    },
  },
  watch: {
    myPageSize(myPageSize) {
      // 当每页条数发生变化时，可能当前页码超出了最大值
      let { myCurrentPage, totalPages } = this;

      if (myCurrentPage > totalPages) {
        this.isEmit = true;
        this.myCurrentPage = totalPages;
        myCurrentPage = totalPages;
      }

      // 触发事件
      this.$emit("size-change", myPageSize, myCurrentPage);
    },
    myCurrentPage(myCurrentPage) {
      if (this.isEmit) {
        this.isEmit = false;
        return;
      }
      // 触发事件
      this.$emit("current-change", myCurrentPage);
    },
  },
};
</script>

<style lang="less" scoped>
.pagination {
  display: flex;
}
.pagination-btns {
  display: flex;
  li {
    width: 30px;
    height: 30px;
    background-color: #f4f4f5;
    color: #606266;
    font-weight: 700;
    margin-right: 10px;
    text-align: center;
    line-height: 30px;
    border-radius: 2px;
    cursor: pointer;
    &.active {
      background-color: #409eff;
      color: #fff;
    }
    &.disabled {
      color: #c0c4cc;
      cursor: not-allowed;
    }
  }
}
.pagination-select {
  outline: none;
  margin: 0 20px 0 10px;
}
.pagination-total {
  font-size: 16px;
  line-height: 30px;
}
</style>
